use ggez::{glam::Vec2,Context, graphics, mint::Point2};

use crate::mover::Mover;
use crate::physics::Physics;
use crate::visual::Visual;
pub struct Balloon {
    physics : Physics,
    visual: Visual,
}

impl Balloon {
    pub fn new(location: Vec2) -> Balloon {
        let velocity = Vec2{x: 0.0, y: 0.0};
        let acceleration = Vec2 { x: 0.0, y: 0.0 };
        let topspeed = 70.0;
        let mass = 10.0;
        let physics = Physics{location, velocity, topspeed, acceleration, mass};
        let color = graphics::Color::new(0.5, 0.5, 0.5, 1.0);
        let size = 16.0;
        let visual = Visual{color, size};
        Balloon {physics, visual}
    }

    pub fn limit(&mut self) -> () {
        if self.physics.velocity.length() > self.physics.topspeed {self.physics.velocity = self.physics.topspeed*self.physics.velocity.normalize()}
    }

}

impl Mover for Balloon {
    fn apply_force(&mut self, force: Vec2) -> () {
        self.physics.acceleration += force;
    }

    fn update(&mut self, ctx: &mut Context) -> () {
        self.physics.acceleration /= self.physics.mass;
        self.physics.velocity += self.physics.acceleration;
        self.physics.velocity -= self.physics.velocity*0.01;
        self.limit();
        
        self.physics.location += self.physics.velocity;
        self.physics.acceleration *= 0.0;
        self.physics.check_edges(ctx);
    }

    fn display(&self, ctx: &mut Context, canvas : &mut graphics::Canvas) -> () {
        let circle = graphics::Mesh::new_circle(
            ctx,
            graphics::DrawMode::fill(),
            Point2{x: self.physics.location.x, y: self.physics.location.y},
            self.visual.size,
            0.1,
            self.visual.color,
        ).unwrap();
        canvas.draw(&circle, graphics::DrawParam::default());
        let circle = graphics::Mesh::new_circle(
            ctx,
            graphics::DrawMode::stroke(2.0),
            Point2{x: self.physics.location.x, y: self.physics.location.y},
            self.visual.size,
            0.1,
            graphics::Color::BLACK,
        ).unwrap();
        canvas.draw(&circle, graphics::DrawParam::default());
    }

    fn get_location(& self) -> Vec2 {
        self.physics.location
    }
}